package com.platform.base.service.impl;

import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.platform.base.domain.*;
import com.platform.base.mapper.*;
import com.platform.common.constant.UserConstants;
import com.platform.common.exception.BusinessException;
import com.platform.common.manager.AsyncManager;
import com.platform.common.utils.DateUtils;
import com.platform.common.utils.StringUtils;
import com.platform.common.utils.netty.NettyUtil;
import com.platform.common.utils.rabbit.RabbitUtils;
import com.platform.common.utils.redis.RedisRun;
import com.platform.common.utils.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.platform.base.service.ICollectorInfoService;
import com.platform.common.core.text.Convert;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 采集器信息Service业务层处理
 * 
 * @author wangqi
 * @date 2020-09-25
 */
@Service
public class CollectorInfoServiceImpl extends ServiceImpl<CollectorInfoMapper,CollectorInfo> implements ICollectorInfoService
{
    @Autowired
    private CollectorInfoMapper collectorInfoMapper;

    @Autowired
    private CollectorTypeMapper collectorTypeMapper;

    @Autowired
    private BaseLocationMapper baseLocationMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RabbitUtils rabbitUtils;



    /**
     * 查询采集器信息列表
     * 
     * @param collectorInfo 采集器信息
     * @return 采集器信息
     */
    @Override
    public List<CollectorInfo> selectCollectorInfoList(CollectorInfo collectorInfo)
    {
        List<CollectorInfo> list = collectorInfoMapper.selectCollectorInfoList(collectorInfo);
        for(CollectorInfo info : list){
            if(redisUtil.hHasKey("online-time", info.getCollectorId())){
                info.setOnlineTime(redisUtil.hget("online-time", info.getCollectorId()).toString());
            }
            if(redisUtil.hHasKey("offline-time", info.getCollectorId())){
                info.setOfflineTime(redisUtil.hget("offline-time", info.getCollectorId()).toString());
            }
        }
        return list;
    }

    /**
     * 查询采集器信息
     *
     * @param collectorId 采集器id
     * @return 采集器信息
     */
    @Override
    public CollectorInfo selectCollectorInfoById(String collectorId)
    {
        return collectorInfoMapper.selectCollectorInfoById(collectorId);
    }

    /**
     * 新增采集器信息
     * 
     * @param collectorInfo 采集器信息
     * @return 结果
     */
    @Override
    public int insertCollectorInfo(CollectorInfo collectorInfo)
    {
        collectorInfo.setCreateTime(DateUtils.getNowDate());
        return collectorInfoMapper.insert(collectorInfo);
    }

    /**
     * 修改采集器信息
     * 
     * @param collectorInfo 采集器信息
     * @return 结果
     */
    @Override
    public int updateCollectorInfo(CollectorInfo collectorInfo)
    {
        collectorInfo.setUpdateTime(DateUtils.getNowDate());
        return collectorInfoMapper.updateById(collectorInfo);
    }

    /**
     * 删除采集器信息对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCollectorInfoByIds(String ids)
    {
        for(String id : Convert.toStrArray(ids)){
            if(redisUtil.hHasKey("sys-netty", id)){
                redisUtil.hdel("sys-netty", id);
            }
            if(redisUtil.hHasKey("online-time", id)){
                redisUtil.hdel("online-time", id);
            }
            if(redisUtil.hHasKey("offline-time", id)){
                redisUtil.hdel("offline-time", id);
            }
        }
        return collectorInfoMapper.deleteCollectorInfoByIds(Convert.toStrArray(ids));
    }

    /**
     * 校验采集器是否唯一
     *
     * @param collectorInfo 采集器信息
     * @return 结果
     */
    @Override
    public String checkCollectorUnique(CollectorInfo collectorInfo){
        CollectorInfo info = collectorInfoMapper.selectById(collectorInfo.getCollectorId());
        if (StringUtils.isNotNull(info))
        {
            return UserConstants.COLLECTOR_ID_NOT_UNIQUE;
        }
        return UserConstants.COLLECTOR_ID_UNIQUE;
    }

    /**
     * 导入采集器信息数据
     *
     * @param infoList 采集器信息数据
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importInfo(List<CollectorInfo> infoList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(infoList) || infoList.size() == 0)
        {
            throw new BusinessException("导入采集器信息数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (CollectorInfo info : infoList)
        {
            try
            {
                //查询采集器类型信息
                CollectorType type = null;
                if(info.getTypeName()!=null && !info.getTypeName().equals("")){
                    List<CollectorType> list = collectorTypeMapper.selectList(new QueryWrapper<CollectorType>().eq("type_name", info.getTypeName()));
                    if(list!=null && list.size()>0){
                        type = list.get(0);
                        info.setTypeId(type.getTypeId());
                    }else{
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + "、采集器 " + info.getCollectorId() + " 采集器类型不存在");
                        continue;
                    }
                }
                //查询采集器地址信息
                BaseLocation location = null;
                if(info.getLocationName()!=null && !info.getLocationName().equals("")){
                    List<BaseLocation> list = baseLocationMapper.selectList(new QueryWrapper<BaseLocation>().eq("location_name", info.getLocationName()));
                    if(list!=null && list.size()>0){
                        location = list.get(0);
                        info.setLocationId(location.getLocationId());
                    }
                }
                // 校验采集器是否存在
                CollectorInfo f = collectorInfoMapper.selectById(info.getCollectorId());
                if (StringUtils.isNull(f))
                {
                    info.setCreateBy(operName);
                    info.setCreateTime(DateUtils.getNowDate());
                    this.insertCollectorInfo(info);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、采集器 " + info.getCollectorId() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    info.setUpdateBy(operName);
                    info.setUpdateTime(DateUtils.getNowDate());
                    this.updateCollectorInfo(info);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、采集器 " + info.getCollectorId() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、采集器 " + info.getCollectorId() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、采集器 " + info.getCollectorId() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 采集器初始化
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String initializeInfo(String[] collectorIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");

                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "0A";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " 00 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "采集器初始化");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00")){
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 初始化成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 初始化失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器初始化失败！共 " + failureNum + " 条采集器初始化失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器初始化成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 设置采集器心跳时间
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String heartInfo(String[] collectorIds, String hex) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "08";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " " + hex + " 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "设置心跳时间");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00")){
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 设置心跳时间成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 设置心跳时间失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器设置心跳时间失败！共 " + failureNum + " 条采集器设置心跳时间失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器设置心跳时间成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 采集器初始化
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String settimeInfo(String[] collectorIds, String hex) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "07";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " " + hex + " 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "设置离线采集时间");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00")){
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 设置离线采集时间成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 设置离线采集时间失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器设置离线采集时间失败！共 " + failureNum + " 条采集器设置离线采集时间失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器设置离线采集时间成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 批量设置阀门开度
     * @param collectorId 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String apertureInfo(String collectorId, String hex) throws InterruptedException {
        //判断采集器是否在线
        boolean status = redisUtil.hHasKey("sys-netty", collectorId);
        if(!status){
            CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
            cinfo.setOnlineStatus(Integer.valueOf(0));
            cinfo.setCollectorId(collectorId);
            collectorInfoMapper.updateById(cinfo);
            return "采集器 " + collectorId + " 已离线";
        }
        //获取采集器高位
        String cenhigh = collectorId.substring(0,2);
        //获取采集器低位
        String cenlow = collectorId.substring(2,4);
        //控制码
        String cont = "06";
        //计算校验码
        int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(hex);
        String check = NettyUtil.get16HexNum(ll);
        if(check.length()<2){
            check = "0" + check;
        }else{
            check = check.substring(check.length()-2);
        }
        String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " " + hex + " 00 00 00 00 00 " + check + " FF ";
        String responseStr = response.replace(" ", "");
        rabbitUtils.writeToClient(collectorId, responseStr, "批量设置阀门开度");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
        return "采集器正在批量设置阀门开度";
    }

    /**
     * 修改服务器地址
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String changeInfo(String[] collectorIds, String[] ips, String[] ports) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "13";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)
                    +NettyUtil.get10HexNum(ips[0])+NettyUtil.get10HexNum(ips[1])+NettyUtil.get10HexNum(ips[2])+NettyUtil.get10HexNum(ips[3])
                    +NettyUtil.get10HexNum(ports[0])+NettyUtil.get10HexNum(ports[1]);;
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            if(ips[0].length()<2){
                ips[0] = "0" + ips[0];
            }else{
                ips[0] = ips[0].substring(ips[0].length()-2);
            }
            if(ips[1].length()<2){
                ips[1] = "0" + ips[1];
            }else{
                ips[1] = ips[1].substring(ips[1].length()-2);
            }
            if(ips[2].length()<2){
                ips[2] = "0" + ips[2];
            }else{
                ips[2] = ips[2].substring(ips[2].length()-2);
            }
            if(ips[3].length()<2){
                ips[3] = "0" + ips[3];
            }else{
                ips[3] = ips[3].substring(ips[3].length()-2);
            }
            if(ports[0].length()<2){
                ports[0] = "0" + ports[0];
            }else{
                ports[0] = ports[0].substring(ports[0].length()-2);
            }
            if(ports[1].length()<2){
                ports[1] = "0" + ports[1];
            }else{
                ports[1] = ports[1].substring(ports[1].length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " " + ips[0] + " " + ips[1] + " " + ips[2] + " " + ips[3] + " " + ports[0] + " " + ports[1] + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "设置服务器地址");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00")){
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 设置服务器地址成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 设置服务器地址失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器设置服务器地址失败！共 " + failureNum + " 条采集器设置服务器地址失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器设置服务器地址成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 查询采集器时间
     * @param collectorIds 采集器信息
     * @return
     * @throws Exception
     */
    @Override
    public String collectInfo(String[] collectorIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "0D";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " 00 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "查询采集器时间");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result==null || result.equals("") || result.equals("0")){
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 查询采集器时间失败");
            }else{
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 采集器时间为："+result);
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，查询采集器时间失败！共 " + failureNum + " 条查询失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，查询采集器时间成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 校准采集器时间
     * @param collectorIds 采集器信息
     * @return
     * @throws Exception
     */
    @Override
    public String correctInfo(String[] collectorIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");
                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "0B";

            Calendar date = Calendar.getInstance();
            String year = String.valueOf(date.get(Calendar.YEAR));
            String month = String.valueOf(date.get(Calendar.MONTH)+1);
            if(month.length()<2){
                month = "0"+month;
            }
            String day = String.valueOf(date.get(Calendar.DATE));
            if(day.length()<2){
                day = "0"+day;
            }
            String hour = String.valueOf(date.get(Calendar.HOUR_OF_DAY));
            if(hour.length()<2){
                hour = "0"+hour;
            }
            String minute = String.valueOf(date.get(Calendar.MINUTE));
            if(minute.length()<2){
                minute = "0"+minute;
            }
            String second = String.valueOf(date.get(Calendar.SECOND));
            if(second.length()<2){
                second = "0"+second;
            }
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)
                    +NettyUtil.get10HexNum(year)+NettyUtil.get10HexNum(month)+NettyUtil.get10HexNum(day)
                    +NettyUtil.get10HexNum(hour)+NettyUtil.get10HexNum(minute)+NettyUtil.get10HexNum(second);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " " + year.substring(2) + " " + month + " " + day + " " + hour + " " + minute + " " + second + " " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "校准采集器时间");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00")){
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 校准时间成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 校准时间失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器校准时间失败！共 " + failureNum + " 条校准时间失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器校准时间成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 获取关联设备
     * @param collectorId 采集器信息
     * @return
     * @throws Exception
     */
    @Override
    public String selectInfo(String collectorId) throws InterruptedException {
        //判断采集器是否在线
        boolean status = redisUtil.hHasKey("sys-netty", collectorId);
        if(!status){
            CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
            cinfo.setOnlineStatus(Integer.valueOf(0));
            cinfo.setCollectorId(collectorId);
            collectorInfoMapper.updateById(cinfo);
            return "采集器 " + collectorId + " 已离线";
        }
        //获取采集器高位
        String cenhigh = collectorId.substring(0,2);
        //获取采集器低位
        String cenlow = collectorId.substring(2,4);
        //控制码
        String cont = "0C";

        //计算校验码
        int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont);
        String check = NettyUtil.get16HexNum(ll);
        if(check.length()<2){
            check = "0" + check;
        }else{
            check = check.substring(check.length()-2);
        }
        String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " 00 00 00 00 00 00 " + check + " FF ";
        String responseStr = response.replace(" ", "");
        rabbitUtils.writeToClient(collectorId, responseStr, "获取所有已登记的设备");
        CountDownLatch countDownLatch = new CountDownLatch(1);
        new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
        countDownLatch.await();
        String result = RedisRun.result;
        if(result==null || result.equals("") ){
            return "采集器 " + collectorId + " 获取关联设备失败";
        }else{
            return "采集器 " + collectorId + " 有" + result + "个关联设备";
        }
    }

    /**
     * 批量数据采集
     * @param collectorId 采集器信息
     * @return
     * @throws Exception
     */
    @Override
    public String checkInfo(String collectorId) throws InterruptedException {
        //判断采集器是否在线
        boolean status = redisUtil.hHasKey("sys-netty", collectorId);
        if(!status){
            CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
            cinfo.setOnlineStatus(Integer.valueOf(0));
            cinfo.setCollectorId(collectorId);
            collectorInfoMapper.updateById(cinfo);
            return "采集器 " + collectorId + " 已离线";
        }
        //获取采集器高位
        String cenhigh = collectorId.substring(0,2);
        //获取采集器低位
        String cenlow = collectorId.substring(2,4);
        //控制码
        String cont = "05";

        //计算校验码
        int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont);
        String check = NettyUtil.get16HexNum(ll);
        if(check.length()<2){
            check = "0" + check;
        }else{
            check = check.substring(check.length()-2);
        }
        String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont + " 00 00 00 00 00 00 " + check + " FF ";
        String responseStr = response.replace(" ", "");
        rabbitUtils.writeToClient(collectorId, responseStr, "采集器"+collectorId+"批量采集数据");
        return "后台正在批量采集";
    }

    /**
     * 供暖标志下发
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String heatInfo(String[] collectorIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");

                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "19";
            //控制码
            String hex = "01";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 " + cont +" "+ hex + " 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "供暖标志下发");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00") || result.equals("01")){
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setHeat("1");
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 供暖标志下发成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 供暖标志下发失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，采集器供暖标志下发失败！共 " + failureNum + " 条采集器供暖标志下发失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器供暖标志下发成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 非供暖标志下发
     * @param collectorIds 热表信息
     * @return
     * @throws Exception
     */
    @Override
    public String heatfInfo(String[] collectorIds) throws InterruptedException {
        int failureNum = 0;
        int successNum = 0;
        StringBuilder failureMsg = new StringBuilder();
        StringBuilder successMsg = new StringBuilder();
        for(String collectorId : collectorIds){
            //判断采集器是否在线
            boolean status = redisUtil.hHasKey("sys-netty", collectorId);
            if(!status){
                failureNum++;
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setOnlineStatus(Integer.valueOf(0));
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 已离线");

                continue;
            }
            //获取采集器高位
            String cenhigh = collectorId.substring(0,2);
            //获取采集器低位
            String cenlow = collectorId.substring(2,4);
            //控制码
            String cont = "19";
            //控制码
            String hex = "02";
            //计算校验码
            int ll = NettyUtil.get10HexNum(cenhigh)+NettyUtil.get10HexNum(cenlow)+NettyUtil.get10HexNum(cont)+NettyUtil.get10HexNum(hex);
            String check = NettyUtil.get16HexNum(ll);
            if(check.length()<2){
                check = "0" + check;
            }else{
                check = check.substring(check.length()-2);
            }
            String response = "AA "+ cenlow +" "+ cenhigh + " 00 00 00 00 "  + cont +" "+ hex + " 00 00 00 00 00 " + check + " FF ";
            String responseStr = response.replace(" ", "");
            rabbitUtils.writeToClient(collectorId, responseStr, "非供暖标志下发");
            CountDownLatch countDownLatch = new CountDownLatch(1);
            new Thread(new RedisRun(countDownLatch, redisUtil, collectorId, cont)).start();
            countDownLatch.await();
            String result = RedisRun.result;
            if(result.equals("00") || result.equals("02")){
                CollectorInfo cinfo = collectorInfoMapper.selectCollectorInfoById(collectorId);
                cinfo.setHeat("0");
                cinfo.setCollectorId(collectorId);
                collectorInfoMapper.updateById(cinfo);
                successNum++;
                successMsg.append("<br/>" + successNum + "、采集器 " + collectorId + " 非供暖标志下发成功");
            }else{
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、采集器 " + collectorId + " 非供暖标志下发失败");
            }
        }
        if(failureNum>0){
            failureMsg.insert(0, "很抱歉，非供暖标志下发失败！共 " + failureNum + " 条非供暖标志下发失败，错误如下：");
            throw new BusinessException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您，采集器非供暖标志下发成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
